from flask_restplus import Resource, Namespace, fields, marshal
from common.decorators import catch_error
from common.responses import ok
from common import constant
from common.response_model import base_model
from common.request_parser import get_parser as base_get_parser
from app.user.decorators import token_required
from app.message.model import Message
from app.message import dao
from app.user.controller import simple_user_model
from app.user.decorators import permission_required, permission_can, check_permission
from app.user.role_service import PermissionKey
from exts import db
from flask import g
api = Namespace('message')

# ---------- model ----------
message_model = base_model.inherit('message_model', {
    "msg_type": fields.String(description='msg_type'),
    'sender': fields.Nested(simple_user_model),
    'receiver': fields.Nested(simple_user_model),
    'title': fields.String(description='title'),
    'content': fields.String(description='content'),
    'ext_parameters': fields.Raw(description='ext_parameters'),
    'create_datetime': fields.DateTime(),
    'is_read': fields.Boolean,
})

# ---------- get parser ----------
get_parser = base_get_parser.copy()
get_parser.replace_argument('sorted_by', type=str, choices=[
    'create_datetime'
], default='id', help='sorted_by')
get_parser.add_argument('get_type', choices=[constant.GetMessageType.SENDER, constant.GetMessageType.RECEIVER],
                        help='获取类型', required=True)


class MessagesResource(Resource):
    @catch_error
    @token_required
    @api.expect(get_parser)
    # @permission_required(PermissionKey.OPERATION_LOG_GET)
    def get(self):
        """获取列表"""
        args = get_parser.parse_args()
        get_type = args.pop('get_type')

        pagination = dao.get_by_page(
            **args,
            receiver_id=g.user_id if get_type == constant.GetMessageType.RECEIVER else None,
            sender_id=g.user_id if get_type == constant.GetMessageType.SENDER else None,

        )
        # 重新根据id获取
        new_items = []
        for item in pagination['items']:
            message = Message.query.filter_by(id=item['id']).first()
            new_items.append(marshal(message, message_model))
        pagination['items'] = new_items

        # 把未读数放进去
        pagination['num_of_unread'] = dao.get_num_of_unread(g.user_id)

        return ok(data=pagination,
                  message='get success')


class ReadAllResource(Resource):
    @catch_error
    @token_required
    def post(self):
        """已读所有消息"""
        messages = Message.query.filter_by(receiver_id=g.user_id, is_read=False).all()
        for message in messages:
            message.is_read = True
        db.session.commit()
        return ok(data={
            "num_of_read": len(messages)
        }, message='read all success')


put_parser = api.parser()
put_parser.add_argument('action', type=str, required=True, choices=['READ'])


class MessageResource(Resource):
    @catch_error
    @token_required
    @api.expect(put_parser)
    def put(self, message_id):
        """修改消息"""
        args = put_parser.parse_args()
        action = args.pop('action')
        if action == 'READ':
            message = Message.query.filter_by(id=message_id).first()
            message.update(is_read=True, commit=True)
            return ok(data=marshal(message, message_model), message='read message success')


# --------- route ----------
api.add_resource(MessagesResource, '/messages')  # 获取接受者消息
api.add_resource(ReadAllResource, '/read_all')  # 已读所有消息

api.add_resource(MessageResource, '/messages/<message_id>/action')  # 已读消息
